package com.hr;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.espirit.common.Form;
import com.espirit.common.FormService;
import com.espirit.eap.manager.DepartmentService;
import com.espirit.eap.sa.Employee;
import com.espirit.eap.util.BigDecimalUtil;
import com.espirit.eap.util.DateUtils;
import com.googlecode.cswish.annotation.ParamScope;
import com.googlecode.cswish.model.PageElements;
import com.googlecode.cswish.model.PageInfo;
import com.googlecode.cswish.model.ParameterMap;
import com.googlecode.cswish.model.Reference;
import com.googlecode.cswish.oosearch.QLInfo;
import com.googlecode.cswish.struts.spring.GenericService;
import com.googlecode.cswish.struts.spring.ObjectFactory;
import com.googlecode.cswish.struts.spring.SearchCallback;

@Service
public class OtItemService extends FormService{
	@Resource
	GenericService genericService;

	@Resource
	DepartmentService departmentService;
	
//	@Resource
	SalaryService salaryService;
	
	public  PageInfo search(final ParameterMap model, int start, int limit,
    		String sort, String dir, boolean newSearch, Reference<QLInfo> qlInfoRef,
    		@ParamScope(visible=false, value="#ps")PageElements ps ,boolean fromMenu
    		) {
		
		final String deptIds = model.getParameter("deptIds");
		SearchCallback callback = departmentService.buildDeptDefaultSearchCallback(model, null, null);
		return genericService.search(model, start, limit, sort, dir, newSearch, qlInfoRef, callback, true, false);
	}
	
	public List<OtItem> getEmployeeOtItems(Employee emp, Date timeFrom,
			Date timeTo) {
		List<OtItem> ret = new ArrayList<OtItem>();
		final String hql = String.format("from " + OtItem.class.getName() + " a where a.realTime between '%s' and '%s' and a.employee.id = %s", 
				DateUtils.format(timeFrom, "yyyy-MM-dd HH:mm:ss"), DateUtils.format(timeTo, "yyyy-MM-dd HH:mm:ss"), emp.getId()
				);
		
		QLInfo qlInfo = new QLInfo(hql, true);
		ret.addAll(genericService.searchByQl(qlInfo, false).getData());
		return ret;
	}

	public void deleteOtItem(Employee emp, Date monthStart, Date monthEnd) {
		List<OtItem> otItems = getEmployeeOtItems(emp, monthStart, monthEnd);
		
		for (OtItem otItem : otItems) {
			genericService.delete(otItem);
		}
	}
	
	@Override
	protected boolean preAdd(Form model) {
		if (model.getEmployee() == null) return false ;
		return true;
	}
	
	@Override
	protected void postAdd(Form model) {
		OtItem form = (OtItem) model;
		if (OtItem.OT_TYPE_EXCHANGING.equals(form.getOtType())){
			Employee employee = model.getEmployee();
			BigDecimal origHours = BigDecimalUtil.getValue(employee.getExchangeHours());
			BigDecimal hours = form.getHours();
			if (hours != null){
				hours = hours.add(origHours);
				employee.setExchangeHours(hours);
				genericService.merge(employee);
			}
		}
		
		getSalaryService().reCalEmpSalary(model.getEmployee());
	}
	
	@Override
	protected boolean preUpdate(Form model) {
		if (model == null) return false ;
		if (model.getEmployee() == null) return false;
		
		
		return true;
	}
	
	@Transactional
	public void update(OtItem model){
		OtItem orig = genericService.load(model);
		BigDecimal origExchangeHours =BigDecimalUtil.getValue(orig.getHours());
		
		model = genericService.update(model);
		BigDecimal nowExchangeHours = BigDecimalUtil.getValue(model.getHours());
		BigDecimal diff = nowExchangeHours.subtract(origExchangeHours);
		
		if (OtItem.OT_TYPE_EXCHANGING.equals(model.getOtType())){
			Employee employee = model.getEmployee();
			BigDecimal hours = employee.getExchangeHours();
			if (hours != null){
				hours = hours.add(diff);
				employee.setExchangeHours(hours);
				genericService.merge(employee);
			}
		}
		
		getSalaryService().reCalEmpSalary(model.getEmployee());
	}
	
	@Transactional
	public void deleteList(List<OtItem> results){
		if (results == null) return ;
		for(OtItem otItem : results){
			if (otItem == null || otItem.getId() == null) continue;
			otItem = genericService.load(OtItem.class, otItem.getId());
			if (otItem != null && OtItem.OT_TYPE_EXCHANGING.equals(otItem.getOtType())){
				BigDecimal hours = BigDecimalUtil.getValue(otItem.getHours());
				
				Employee employee = otItem.getEmployee();
				if (employee != null){
					BigDecimal exchangeHours = BigDecimalUtil.getValue(employee.getExchangeHours());
					exchangeHours = exchangeHours.add(hours);
					employee.setExchangeHours(exchangeHours);
					genericService.merge(employee);
				}
			}
			Employee emp = otItem.getEmployee();
			genericService.delete(otItem);
			
			getSalaryService().reCalEmpSalary(emp);
		}
		
	}
	
	public SalaryService getSalaryService(){
		if (salaryService == null){
			salaryService = ObjectFactory.getInstance().getBean(SalaryService.class, true);
		}
		return salaryService;
	}
}
